home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
vector.lha
/
vector
/
cvector.h
< prev
next >
Wrap
C/C++ Source or Header
|
1991-11-23
|
4KB
|
174 lines
#ifndef _CVECTOR_H
#define _CVECTOR_H
#include <stream.h>
#include <math.h>
#include "vector_names.h"
// This is a template for a Cartesian vector class.
// The usual operators are supplied.
#define CartesianVectorDeclare(T) \
class CVec(T) { \
public: \
static errorHandler error; \
static void badvec(int, const char *); \
static errorHandler setErrorHandler(errorHandler); \
\
T &operator[](int i) { return x[i]; } \
T operator()(int i) const { return x[i]; } \
operator T*() { return x; } \
\
CVec(T)() {} \
\
CVec(T)(T xval, T yval, T zval) { \
x[0] = xval; x[1] = yval; x[2] = zval; \
} \
\
CVec(T)(const CVec(T) &v) { \
x[0] = v(0); x[1] = v(1); x[2] = v(2); \
} \
\
T magnitude() const { \
return sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]); \
} \
\
CVec(T) &normalize(); \
\
CVec(T) &operator+=(const CVec(T) &v) { \
x[0] += v(0); \
x[1] += v(1); \
x[2] += v(2); \
return *this; \
} \
\
CVec(T) &operator-=(const CVec(T) &v) { \
x[0] -= v(0); \
x[1] -= v(1); \
x[2] -= v(2); \
return *this; \
} \
\
CVec(T) &operator*=(T s) { \
x[0] *= s; \
x[1] *= s; \
x[2] *= s; \
return *this; \
} \
\
CVec(T) &operator/=(T s) { \
T recip = 1.0 / s; \
x[0] *= recip; \
x[1] *= recip; \
x[2] *= recip; \
return *this; \
} \
\
protected: \
T x[3]; \
}; \
\
/* -V */ \
inline CVec(T) operator-(const CVec(T) &v) \
{ \
return CVec(T)(-v(0), -v(1), -v(2)); \
} \
\
/* s * V */ \
inline CVec(T) operator*(T s, const CVec(T) &v) \
{ \
return CVec(T)(s * v(0), s * v(1), s * v(2)); \
} \
\
/* V * s */ \
inline CVec(T) operator*(const CVec(T) &v, T s) { \
return s * v; \
} \
\
/* V / s */ \
inline CVec(T) operator/(const CVec(T) &v, T s) \
{ \
T recip = 1.0 / s; \
return CVec(T)(v(0) * recip, v(1) * recip, v(2) * recip); \
} \
\
/* V + V */ \
inline CVec(T) operator+(const CVec(T) &a, const CVec(T) &b) \
{ \
return CVec(T)(a(0) + b(0), a(1) + b(1), a(2) + b(2)); \
} \
\
/* V - V */ \
inline CVec(T) operator-(const CVec(T) &a, const CVec(T) &b) \
{ \
return CVec(T)(a(0) - b(0), a(1) - b(1), a(2) - b(2)); \
} \
\
/* V cross V */ \
inline CVec(T) operator^(const CVec(T) &a, const CVec(T) &b) \
{ \
return CVec(T)(a(1) * b(2) - a(2) * b(1), \
a(2) * b(0) - a(0) * b(2), \
a(0) * b(1) - a(1) * b(0)); \
} \
\
/* V dot V */ \
inline T operator*(const CVec(T) &a, const CVec(T) &b) \
{ \
return a(0) * b(0) + a(1) * b(1) + a(2) * b(2); \
} \
\
/* V == V (no fuzz for comparison) */ \
inline int operator==(const CVec(T) &a, const CVec(T) &b) \
{ \
return (a(0) == b(0)) && (a(1) == b(1)) && (a(2) == b(2)); \
} \
\
/* V != V (no fuzz for comparison) */ \
inline int operator!=(const CVec(T) &a, const CVec(T) &b) { \
return !(a == b); \
} \
\
ostream &operator<<(ostream &o, const CVec(T) &v);
#define CartesianVectorImplement(T) \
\
errorHandler CVec(T)::error = &CVec(T)::badvec; \
\
void CVec(T)::badvec(int code, const char *msg) { \
cerr << "CVec(T): error " << code << ": " \
<< msg << endl; \
} \
\
errorHandler CVec(T)::setErrorHandler(errorHandler e) { \
errorHandler old = CVec(T)::error; \
CVec(T)::error = e; \
return old; \
} \
\
CVec(T) &CVec(T)::normalize() { \
T mag = this->magnitude(); \
\
if (mag != 0.0) { \
mag = 1.0 / mag; \
x[0] *= mag; \
x[1] *= mag; \
x[2] *= mag; \
} else { \
(*error)(0, "magnitude=0 in normalize"); \
} \
\
return *this; \
} \
\
ostream &operator<<(ostream &o, const CVec(T) &v) { \
return o << "( " << v(0) << ' ' \
<< v(1) << ' ' << v(2) << " )"; \
}
CartesianVectorDeclare(float);
typedef CVec(float) Vector;
#endif /*_CVECTOR_H*/